package com.zzh.bridge;

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import androidx.fragment.app.Fragment;

import com.zzh.bridge_annotation.TagImpl;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dalvik.system.DexFile;

public class BridgeIntent {

    public static final String TAG = BridgeIntent.class.getSimpleName();


    // 需要拦截的界面的集合
    private static final List<String> sInterceptPath = new ArrayList<String>();
    // 添加跳转的intent
    private static final Map<String, Bridge> sIntentMaps = new HashMap<>();

    private static Bridge sIntentIntercept;


    // 拦截用
    public static void setIntentIntercept(Bridge intentIntercept) {
        BridgeIntent.sIntentIntercept = intentIntercept;
    }

    public static synchronized void init(Context context) {
        if (sIntentMaps.size() > 0) {
            throw new ExceptionInInitializerError("已经初始化过了 请不要重复调用");
        }
        //获得当前包下以及子包下的所有类
        List<String> allClassStr = getClassName("com.zzh.page", context);
        for (String s : allClassStr) {
            Log.i(TAG, ">>>page> str >>>" + s);
            try {
                Class cls = Class.forName(s);
                Annotation annotation = cls.getAnnotation(TagImpl.class);
                if (annotation != null) {
                    Object object = cls.newInstance();
                    if (object instanceof Bridge) {
                        Bridge intent = (Bridge) object;
                        String moudelName = intent.getName();
                        if (sIntentMaps.containsKey(moudelName)) {
                            break;
                        }
                        sIntentMaps.put(moudelName, intent);
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }


    public static void start(@NotNull String moudelType, @NotNull String pageType, @NotNull Context context) {
        start(moudelType, pageType, context, null);
    }

    public static void start(@NotNull String moudelType, @NotNull String pageType, @NotNull Context context, Bundle bundle) {
        start(moudelType, pageType, context, bundle, -1);
    }

    public static void start(@NotNull String moudelType, @NotNull String pageType, @NotNull Context context, int requestCode) {
        start(moudelType, pageType, context, null, requestCode);
    }

    public static void start(@NotNull String moudelType, @NotNull String pageType, @NotNull Context context, Bundle bundle, int requestCode) {
        disStart(moudelType, pageType, context, bundle, requestCode);
    }


    public static Fragment getFragment(@NotNull String moudelType, @NotNull String pageType) {
        Object object = getBridgeObject(moudelType, pageType);
        if (object != null && object instanceof Fragment) {
            return (Fragment) object;
        } else {
            Log.i(TAG, "没有找到对应的fragment");
        }
        return null;
    }




    public static Object getBridgeObject(@NotNull String moudelType, @NotNull String pageType) {
        Class cls = getBridgeClass(moudelType, pageType);
        if (cls == null) {
            return null;
        }
        Object object = null;
        try {
            object = cls.newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return object;
    }

    private static Class getBridgeClass(@NotNull String moudelType, @NotNull String pageType) {
        if (sIntentMaps.containsKey(moudelType)) {
            Bridge bridge = sIntentMaps.get(moudelType);
            return bridge.get(pageType);
        }
        return null;
    }


    private static void disStart(String moudelType, String pageType, Context context, Bundle bundle, int requestCode) {
        if (TextUtils.isEmpty(moudelType)) {
            Log.i(TAG, "沒有选中的moudel");
            return;
        }
        if (TextUtils.isEmpty(pageType)) {
            Log.i(TAG, "沒有选中的page");
        }
        Bridge bridge = null;
        if (sInterceptPath.contains(moudelType + File.separator + pageType)) {
            Log.i(TAG, String.format("拦截到了 %s", pageType));
            bridge = sIntentIntercept;
        } else {
            if (sIntentMaps.containsKey(moudelType)) {
                bridge = sIntentMaps.get(moudelType);
            }
        }
        skip(bridge, pageType, context, bundle, requestCode);
    }

    private static final void skip(Bridge bridge, String pageType, Context context, Bundle bundle, int requestCode) {
        if (bridge == null) {
            Log.i(TAG, "沒有指定的跳转器");
            return;
        }
        bridge.start(pageType, context, bundle, requestCode);
    }

    private static List<String> getClassName(String packageName, Context context) {
        List<String> classNameList = new ArrayList<String>();
        try {
            //通过DexFile查找当前的APK中可执行文件
            DexFile df = new DexFile(context.getPackageCodePath());
            //获取df中的元素  这里包含了所有可执行的类名 该类名包含了包名+类名的方式
            Enumeration<String> enumeration = df.entries();
            //遍历
            while (enumeration.hasMoreElements()) {
                String className = (String) enumeration.nextElement();
                //在当前所有可执行的类里面查找包含有该包名的所有类
                if (className.contains(packageName)) {
                    classNameList.add(className);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return classNameList;
    }


}